using System.Text.RegularExpressions;
using Dapper;
using MySql.Data.MySqlClient;
using WebApi.Models;

namespace WebApi.Services;

public class ProjectService: IProjectService
{
    private readonly string _conStr;
    private readonly IHttpClientFactory _clientFactory;
    private readonly ILogger<ProjectService> _logger;

    public ProjectService(IConfiguration configuration, IHttpClientFactory clientFactory, ILogger<ProjectService> logger)
    {
        _conStr = configuration.GetConnectionString("Smart");
        _clientFactory = clientFactory;
        _logger = logger;
    }

    public async Task<IEnumerable<ProjectModel>> GetAllProjects()
    {
        await using MySqlConnection conn = new MySqlConnection(_conStr);
        var querySql = "select id, title, url, description from leftTable;";
        return await conn.QueryAsync<ProjectModel>(querySql);
    }

    public async Task<int> InsertUserProjectModels(IEnumerable<UserProjectModel> models)
    {
        await using MySqlConnection conn = new MySqlConnection(_conStr);
        var deleteSql = "delete from rightTable;";
        var insertSql = "insert into rightTable values(@id, @createTime);";

        try
        {
            foreach (var model in models)
            {
                model.CreateTime = DateTime.UtcNow;
            }
            
            conn.Open();
            var trans = await conn.BeginTransactionAsync();
            await conn.ExecuteAsync(deleteSql, models, trans);
            var res = await conn.ExecuteAsync(insertSql, models, trans);
            await trans.CommitAsync();
            return res;
        }
        catch (Exception e)
        {
            _logger.LogError(e.Message);
            return -1;
        }
    }
    

    private static readonly Regex ProjectRg =
        new Regex(
            "</i>\\s*<a title=\".*?\" class=\"repository\" target=\"_blank\" style=\"(.*?)\" sa_evt=\"repoClick\" sa_location=\"组织页面\" sa_url=\"\" sa_repo_id=\"(?<id>\\d*)\" href=\"(?<url>.*?)\">(?<title>.*?)</a>(.*?)<p class='description'>(?<desc>.*?)</p>", RegexOptions.Singleline);
    
    public async Task<int> InitDataBase()
    {
        // var count = await LeftTableCount();
        // if (count > 0) return 0;
        
        var client = _clientFactory.CreateClient("Gitee");
        
        #region obsolete

        // var html = await client.GetStringAsync("/organizations/smartide/projects");
        // var matches = ProjectRg.Matches(html);
        //
        // var models = matches.Select(m => new ProjectModel
        // {
        //     Id = int.Parse(m.Groups["id"].Value),
        //     Title = m.Groups["title"].Value,
        //     Url = m.Groups["url"].Value,
        //     Description = m.Groups["desc"].Value.Trim('\n')
        // });

        #endregion

        var models = new List<ProjectModel>();
        GetAllProjects(models, client, 1);
        
        return await InsertProjects(models);
    }

    private void GetAllProjects(List<ProjectModel> models, HttpClient client, int pageNum)
    {
        var res = client.GetFromJsonAsync<List<ProjectModel>>($"/api/v5/orgs/smartide/repos?type=all&page={pageNum}&per_page=5").GetAwaiter().GetResult();
        if (res != null && res.Count > 0)
        {
            models.AddRange(res);
            GetAllProjects(models, client, pageNum + 1);
        }
    }

    private async Task<int> LeftTableCount()
    {
        await using MySqlConnection conn = new MySqlConnection(_conStr);
        var querySql = "select count(1) num from leftTable;";
        return await conn.ExecuteScalarAsync<int>(querySql);
    }
    private async Task<int> InsertProjects(IEnumerable<ProjectModel> models)
    {
        await using MySqlConnection conn = new MySqlConnection(_conStr);
        var insertSql = "insert into leftTable values(@id, @title, @url, @description);";
        return await conn.ExecuteAsync(insertSql, models);
    }
}